package com.sicau.smarttraceplatform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sicau.smarttraceplatform.entity.Trace;
import com.sicau.smarttraceplatform.entity.vo.goodtrace.GoodTraceVO;
import com.sicau.smarttraceplatform.mapper.GoodTraceMapper;
import com.sicau.smarttraceplatform.mapper.TraceMapper;
import com.sicau.smarttraceplatform.service.GoodTraceService;
import com.sicau.smarttraceplatform.utils.RedisHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 农产品溯源信息 服务实现类
 * </p>
 *
 * @author ttxxi
 * @since 2020-06-03
 */
@Service
@Slf4j
public class GoodTraceServiceImpl implements GoodTraceService {

    /**
     * 缓存key的前缀
     */
    private static final String CACHE_PREFIX = "goodTrace";
    /**
     * 添加到缓存数据的有效时间
     */
    private static final int TIME_OUT = 12;

    /**
     * 添加到缓存数据的有效时间的单位
     */
    private static final TimeUnit TIME_UNIT = TimeUnit.HOURS;

    /**
     * 添加到临时缓存数据的有效时间
     */
    private static final int TMP_TIME_OUT = 1;

    /**
     * 添加到临时缓存数据的有效时间的单位
     */
    private static final TimeUnit TMP_TIME_UNIT = TimeUnit.MINUTES;

    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private GoodTraceMapper goodTraceMapper;
    @Resource
    private TraceMapper traceMapper;

    @Override
    public GoodTraceVO queryByTraceId(String traceId) {

        log.info("开始溯源id为【{}】的农产品的溯源信息查询",traceId);
        //判空
        if (StringUtils.isEmpty(traceId)) {
            return null;
        }



        log.info("从缓存中获取农产品溯源信息");
        RedisHelper<GoodTraceVO> redisHelper = new RedisHelper<>(redisTemplate);
        GoodTraceVO goodTraceVO = redisHelper.getExpire(CACHE_PREFIX+traceId);

        //判断缓存中是否有值
        if (goodTraceVO == null) {
            log.info("从缓存中取值为空，开始数据库查询");

            //判断溯源id是否存在
            Trace trace = traceMapper.selectOne(new LambdaQueryWrapper<Trace>().eq(Trace::getTraceId, traceId));
            if (trace == null){
                log.info("没有溯源id为【{}】的农产品", traceId);
                return saveEmptyCache(CACHE_PREFIX+traceId,redisHelper);
            }
            goodTraceVO = goodTraceMapper.selectGoodsTraceInfo(traceId);
            if (goodTraceVO ==null){
                return saveEmptyCache(CACHE_PREFIX+traceId,redisHelper);
            }

            log.info("将从数据库查询到的数据添加入缓存");
            redisHelper.set(CACHE_PREFIX + traceId, goodTraceVO, TIME_OUT, TIME_UNIT);
            return goodTraceVO;
        }


        log.info("从缓存中取出农产品溯源信息：{}",goodTraceVO);
        return goodTraceVO;
    }

    /**
     * 存入对应key值的一个空对象，防止穿透
     * @return 空对象
     */
    private GoodTraceVO saveEmptyCache(String key,RedisHelper<GoodTraceVO> redisHelper) {
        log.info("查询数据库为空，为防止穿透，存入key【{}】，对应value为空对象，超时时间为【{}{}】", key, TMP_TIME_OUT, TMP_TIME_UNIT.toString());
        GoodTraceVO goodTraceVO = new GoodTraceVO();
        redisHelper.set(key,goodTraceVO,TMP_TIME_OUT,TMP_TIME_UNIT);
        return goodTraceVO;
    }

}
